package managers.conversationManager.services;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

import managers.OptionsManager;
import managers.conversationManager.ConversationManager;
import managers.conversationManager.GenericSocket;
import managers.messengerManager.services.Service;
import spotGUI.floatingChatGUI.FloatingChat;
import spotGUI.floatingChatGUI.ReceiveFilePanel;
import utils.StackTracePrinter;
import audio.AudioManager;

public class ReceiveFile extends Service {

	public static final int FT_ACCEPT = 0;
	public static final int FT_REFUSE = -1;

	private GenericSocket socket;

	private DataInputStream dis;
	private DataOutputStream dos;

	private ConversationManager convManager = ConversationManager.getSharedInstance();
	private Properties soundOptions = OptionsManager.getSharedInstance().getOptionGroup("soundPopup");
	private int incomingUser;
	
	private FloatingChat relatedChat;
	private ReceiveFilePanel ftPanel;
	private int currentChoice;

	public ReceiveFile (GenericSocket socket) throws IOException {

		super("ReceiveFile");
		this.socket = socket;
		dis = new DataInputStream(socket.getInputStream());
		dos = new DataOutputStream(socket.getOutputStream());

	
		incomingUser = dis.readInt();
		relatedChat = convManager.getChatManager().getChat(incomingUser);
		
	}

	@Override
	public void run() {

		try {
	
			ftPanel = relatedChat.getFiletransferManager().getReceiveFileFeedback();
			ftPanel.enableChoiceButtons(true);
			
			playSound("fileTransferRequest");
			relatedChat.setVisible(true);
			ftPanel.setVisible(true);
			ftPanel.lock(true);
			askForFileTransfer();
			ftPanel.enableChoiceButtons(false);
			if (currentChoice == FT_ACCEPT) {
				ftPanel.updateLogBar("Ricezione in corso...", null);
				ftPanel.setReceiving(true);
				dos.writeInt(FT_ACCEPT);
				receiveFile();
				ftPanel.lock(false);
				playSound("fileTransferComplete");
				ftPanel.setReceiving(false);
				ftPanel.updateLogBar("File ricevuto correttamente.", null);
				relatedChat.setVisible(true);
			}
			else {
				dos.writeInt(FT_REFUSE);
				ftPanel.updateLogBar("Ricezione file annullata.", null);
				ftPanel.lock(false);
			}
			closeTransfer();
		} catch (Exception e) {
			StackTracePrinter.print(e);
			playSound("fileTransferError");
			ftPanel.setReceiving(false);
			ftPanel.updateLogBar("Errore durante la ricezione del file.", null);
			closeTransfer();
			ftPanel.lock(false);
			relatedChat.setVisible(true);
		}
	}

	private void closeTransfer() {
		try {
			socket.close();
			dis.close();
			dos.close();
		} catch (IOException e) {
			//do nothing
			StackTracePrinter.print(e);
		}
	}
	
	private void playSound(String event) {
		if (soundOptions.getProperty(event+".SOUND").equals("true"))
			try {
				String[] attributes = soundOptions.getProperty(event+".SOUNDPATH").split(",");
				AudioManager.getSharedInstance().play(attributes[0], attributes);
			} catch (Exception e) {
				//do nothing
				StackTracePrinter.print(e);
			}
	}


	private void receiveFile() throws IOException {
		int nameLenght = dis.readInt();
		char[] nameInChars = new char[nameLenght];
		for (int i = 0; i < nameLenght; i++) {
			nameInChars[i] = dis.readChar();
		}
		String fileName = new String(nameInChars);
		
		int fileLenght = dis.readInt();
		String path = OptionsManager.getSharedInstance().getOptionGroup("fileTransfer").getProperty("filesFolder");
		
		byte[] bytes = new byte[fileLenght];
		DataInputStream is = new DataInputStream(socket.getInputStream());
		is.readFully(bytes);
		File f = new File(path+"/"+fileName);
		f.createNewFile();
		FileOutputStream fos = new FileOutputStream(f);
		fos.write(bytes);
		fos.close();
	}

	private synchronized void askForFileTransfer () throws InterruptedException {
		ftPanel.updateLogBar(relatedChat.getReceiverName()+" vuole inviarti un file.", null);
		ftPanel.setCurrentFileTransfer(this);
		ftPanel.enableChoiceButtons(true);
		ftPanel.setVisible(true);
		wait();
	}


	public synchronized void wakeUp () {
		notify();
	}

	public void setChoice (int choice) {
		currentChoice = choice;
	}

}
